package com.bml.client.secret.demo.config;

import com.bml.client.secret.demo.filter.JwtAuthenticationTokenFilter;
import com.bml.client.secret.demo.handler.ClientLogoutSuccessHandler;
import com.bml.client.secret.demo.handler.LoginResultHandler;
import com.bml.client.secret.demo.handler.VistAccessDeniedHandler;
import com.bml.client.secret.demo.handler.VistAuthenticationEntryPoint;
import com.bml.client.secret.demo.service.AuthClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author: baiml
 * @Title: ClientWebSecretConfig
 * @ProjectName: 中台技术平台
 * @Depart 中台研发部
 * @Description:
 * @date: 2021/6/29 16:08
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class ClientWebSecretConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private LoginResultHandler loginResultHandler;

    @Autowired
    private AuthClientService authClientService;

    @Autowired
    private VistAccessDeniedHandler vistAccessDeniedHandler;

    @Autowired
    private VistAuthenticationEntryPoint vistAuthenticationEntryPoint;
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private ClientLogoutSuccessHandler clientLogoutSuccessHandler;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().
                antMatchers("/client/user/**").
                permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login").permitAll()
                .usernameParameter("loginUserName")
                .passwordParameter("loginPassword")
                .successHandler(loginResultHandler)
                .failureHandler(loginResultHandler)
                .and()
                .logout().logoutSuccessHandler(clientLogoutSuccessHandler).permitAll()
                .and()
                //没有权限处理
                .exceptionHandling().accessDeniedHandler(vistAccessDeniedHandler)
                .and()
                .exceptionHandling().authenticationEntryPoint(vistAuthenticationEntryPoint);
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        // 禁用缓存
        http.headers().cacheControl();

        //开启跨域访问
        http.cors().disable();
        //关闭跨域攻击
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) {
        //对于在header里面增加token等类似情况，放行所有OPTIONS请求。
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
//      web.ignoring().antMatchers("/index.html", "/static/**", "/login_p", "/favicon.ico")
//              // 给 swagger 放行；不需要权限能访问的资源
//              .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/images/**", "/webjars/**", "/v2/api-docs", "/configuration/ui", "/configuration/security");

    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(authClientService).passwordEncoder(passwordEncoder());
    }
}
